/* ***************************************************************************
 *
 * ftsystem.h
 *
 * FreeType low-level system interface definition (specification).
 *
 * Copyright (C) 1996-2021 by
 * David Turner, Robert Wilhelm, and Werner Lemberg.
 *
 * This file is part of the FreeType project, and may only be used,
 * modified, and distributed under the terms of the FreeType project
 * license, LICENSE.TXT.  By continuing to use, modify, or distribute
 * this file you indicate that you have read the license and
 * understand and accept it fully.
 *
 */


#ifndef FTSYSTEM_H_
#define FTSYSTEM_H_


FT_BEGIN_HEADER


/* *************************************************************************
 *
 * @section:
 * system_interface
 *
 * @title:
 * System Interface
 *
 * @abstract:
 * How FreeType manages memory and i/o.
 *
 * @description:
 * This section contains various definitions related to memory management
 * and i/o access.  You need to understand this information if you want to
 * use a custom memory manager or you own i/o streams.
 *
 */


/* *************************************************************************
 *
 * M E M O R Y   M A N A G E M E N T
 *
 */


/* *************************************************************************
 *
 * @type:
 * FT_Memory
 *
 * @description:
 * A handle to a given memory manager object, defined with an
 * @FT_MemoryRec structure.
 *
 */
typedef struct FT_MemoryRec_ *FT_Memory;


/* *************************************************************************
 *
 * @functype:
 * FT_Alloc_Func
 *
 * @description:
 * A function used to allocate `size` bytes from `memory`.
 *
 * @input:
 * memory ::
 * A handle to the source memory manager.
 *
 * size ::
 * The size in bytes to allocate.
 *
 * @return:
 * Address of new memory block.  0~in case of failure.
 *
 */
typedef void *(*FT_Alloc_Func)(FT_Memory memory, long size);


/* *************************************************************************
 *
 * @functype:
 * FT_Free_Func
 *
 * @description:
 * A function used to release a given block of memory.
 *
 * @input:
 * memory ::
 * A handle to the source memory manager.
 *
 * block ::
 * The address of the target memory block.
 *
 */
typedef void (*FT_Free_Func)(FT_Memory memory, void *block);


/* *************************************************************************
 *
 * @functype:
 * FT_Realloc_Func
 *
 * @description:
 * A function used to re-allocate a given block of memory.
 *
 * @input:
 * memory ::
 * A handle to the source memory manager.
 *
 * cur_size ::
 * The block's current size in bytes.
 *
 * new_size ::
 * The block's requested new size.
 *
 * block ::
 * The block's current address.
 *
 * @return:
 * New block address.  0~in case of memory shortage.
 *
 * @note:
 * In case of error, the old block must still be available.
 *
 */
typedef void *(*FT_Realloc_Func)(FT_Memory memory, long cur_size, long new_size, void *block);


/* *************************************************************************
 *
 * @struct:
 * FT_MemoryRec
 *
 * @description:
 * A structure used to describe a given memory manager to FreeType~2.
 *
 * @fields:
 * user ::
 * A generic typeless pointer for user data.
 *
 * alloc ::
 * A pointer type to an allocation function.
 *
 * free ::
 * A pointer type to an memory freeing function.
 *
 * realloc ::
 * A pointer type to a reallocation function.
 *
 */
struct FT_MemoryRec_ {
    void *user;
    FT_Alloc_Func alloc;
    FT_Free_Func free;
    FT_Realloc_Func realloc;
};


/* *************************************************************************
 *
 * I / O   M A N A G E M E N T
 *
 */


/* *************************************************************************
 *
 * @type:
 * FT_Stream
 *
 * @description:
 * A handle to an input stream.
 *
 * @also:
 * See @FT_StreamRec for the publicly accessible fields of a given stream
 * object.
 *
 */
typedef struct FT_StreamRec_ *FT_Stream;


/* *************************************************************************
 *
 * @struct:
 * FT_StreamDesc
 *
 * @description:
 * A union type used to store either a long or a pointer.  This is used
 * to store a file descriptor or a `FILE*` in an input stream.
 *
 */
typedef union FT_StreamDesc_ {
    long value;
    void *pointer;
} FT_StreamDesc;


/* *************************************************************************
 *
 * @functype:
 * FT_Stream_IoFunc
 *
 * @description:
 * A function used to seek and read data from a given input stream.
 *
 * @input:
 * stream ::
 * A handle to the source stream.
 *
 * offset ::
 * The offset of read in stream (always from start).
 *
 * buffer ::
 * The address of the read buffer.
 *
 * count ::
 * The number of bytes to read from the stream.
 *
 * @return:
 * The number of bytes effectively read by the stream.
 *
 * @note:
 * This function might be called to perform a seek or skip operation with
 * a `count` of~0.  A non-zero return value then indicates an error.
 *
 */
typedef unsigned long (*FT_Stream_IoFunc)(FT_Stream stream, unsigned long offset, unsigned char *buffer,
    unsigned long count);


/* *************************************************************************
 *
 * @functype:
 * FT_Stream_CloseFunc
 *
 * @description:
 * A function used to close a given input stream.
 *
 * @input:
 * stream ::
 * A handle to the target stream.
 *
 */
typedef void (*FT_Stream_CloseFunc)(FT_Stream stream);


/* *************************************************************************
 *
 * @struct:
 * FT_StreamRec
 *
 * @description:
 * A structure used to describe an input stream.
 *
 * @input:
 * base ::
 * For memory-based streams, this is the address of the first stream
 * byte in memory.  This field should always be set to `NULL` for
 * disk-based streams.
 *
 * size ::
 * The stream size in bytes.
 *
 * In case of compressed streams where the size is unknown before
 * actually doing the decompression, the value is set to 0x7FFFFFFF.
 * (Note that this size value can occur for normal streams also; it is
 * thus just a hint.)
 *
 * pos ::
 * The current position within the stream.
 *
 * descriptor ::
 * This field is a union that can hold an integer or a pointer.  It is
 * used by stream implementations to store file descriptors or `FILE*`
 * pointers.
 *
 * pathname ::
 * This field is completely ignored by FreeType.  However, it is often
 * useful during debugging to use it to store the stream's filename
 * (where available).
 *
 * read ::
 * The stream's input function.
 *
 * close ::
 * The stream's close function.
 *
 * memory ::
 * The memory manager to use to preload frames.  This is set internally
 * by FreeType and shouldn't be touched by stream implementations.
 *
 * cursor ::
 * This field is set and used internally by FreeType when parsing
 * frames.  In particular, the `FT_GET_XXX` macros use this instead of
 * the `pos` field.
 *
 * limit ::
 * This field is set and used internally by FreeType when parsing
 * frames.
 *
 */
typedef struct FT_StreamRec_ {
    unsigned char *base;
    unsigned long size;
    unsigned long pos;

    FT_StreamDesc descriptor;
    FT_StreamDesc pathname;
    FT_Stream_IoFunc read;
    FT_Stream_CloseFunc close;

    FT_Memory memory;
    unsigned char *cursor;
    unsigned char *limit;
} FT_StreamRec;

/* */


FT_END_HEADER

#endif /* FTSYSTEM_H_ */


/* END */
